﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Imaging;

namespace Xajhzwb.Components.Helper
{
    public class ImageHelper
    {
        public static string AllowExt = ".jpe|.jpeg|.jpg|.png|.tif|.tiff|.bmp|.gif";
        public static string Filter = "Picture Files|*.jpg;*.jpeg;*.png;*.bmp;*.gif;*.tiff|All Files|*.*";
        private static long imageQulity = 80;

        #region WaterMarkPosition
        public enum WaterMarkPosition
        {
            Absolute,
            TopLeft,
            TopRight,
            TopMiddle,
            BottomLeft,
            BottomRight,
            BottomMiddle,
            MiddleLeft,
            MiddleRight,
            Center
        }
        #endregion

        #region DrawWaterMarkImage
        public static Image DrawWaterMarkImage(Image sourceImage, Image maskImage, WaterMarkPosition position, float lucencyValue, Color backgroundColor)
        {
            int xPoint = 0;
            int yPoint = 0;

            switch(position)
            {
                case WaterMarkPosition.Absolute:
                    break;
                case WaterMarkPosition.TopLeft:
                    xPoint = 0;
                    yPoint = 0;
                    break;
                case WaterMarkPosition.TopRight:
                    xPoint = sourceImage.Width - maskImage.Width;
                    yPoint = 0;
                    break;
                case WaterMarkPosition.TopMiddle:
                    xPoint = (sourceImage.Width - maskImage.Width) / 2;
                    yPoint = 0;
                    break;
                case WaterMarkPosition.BottomLeft:
                    xPoint = 0;
                    yPoint = sourceImage.Height - maskImage.Height;
                    break;
                case WaterMarkPosition.BottomRight:
                    xPoint = sourceImage.Width - maskImage.Width;
                    yPoint = sourceImage.Height - maskImage.Height;
                    break;
                case WaterMarkPosition.BottomMiddle:
                    xPoint = (sourceImage.Width - maskImage.Width) / 2;
                    yPoint = sourceImage.Height - maskImage.Height;
                    break;
                case WaterMarkPosition.MiddleLeft:
                    xPoint = 0;
                    yPoint = (sourceImage.Height - maskImage.Height) / 2;
                    break;
                case WaterMarkPosition.MiddleRight:
                    xPoint = sourceImage.Width - maskImage.Width;
                    yPoint = (sourceImage.Height - maskImage.Height) / 2;
                    break;
                case WaterMarkPosition.Center:
                    xPoint = (sourceImage.Width - maskImage.Width) / 2;
                    yPoint = (sourceImage.Height - maskImage.Height) / 2;
                    break;
                default:
                    break;
            }

            bool sourceImageIsGif = sourceImage.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Gif);
            if(sourceImageIsGif)
            {
                Bitmap bmp = new Bitmap(sourceImage.Width, sourceImage.Height, PixelFormat.Format32bppArgb);
                using(Graphics g = Graphics.FromImage(bmp))
                {
                    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                    g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;

                    g.Clear(backgroundColor);

                    g.DrawImage(sourceImage, 0, 0);

                    using(ImageAttributes imgAttrib = ImageAttrib(lucencyValue))
                    {
                        g.DrawImage(maskImage, new Rectangle(xPoint, yPoint, maskImage.Width, maskImage.Height),
                            0, 0, maskImage.Width, maskImage.Height, GraphicsUnit.Pixel, imgAttrib);
                    }
                }

                return bmp as Image;
            }
            else
            {
                using(Graphics g = Graphics.FromImage(sourceImage))
                {
                    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                    g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                    using(ImageAttributes imgAttrib = ImageAttrib(lucencyValue))
                    {
                        g.DrawImage(maskImage, new Rectangle(xPoint, yPoint, maskImage.Width, maskImage.Height),
                            0, 0, maskImage.Width, maskImage.Height, GraphicsUnit.Pixel, imgAttrib);
                    }
                }

                return sourceImage;
            }
        }

        public static string DrawWaterMarkImage(Image sourceImage, Image maskImage, WaterMarkPosition position, float lucencyValue, Color backgroundColor,
                                               ImageFormat imageFormat, string maskedImageSavePath)
        {
            long imageQulity = 0;

            using(Image img = DrawWaterMarkImage(sourceImage.Clone() as Image, maskImage, position, lucencyValue, backgroundColor))
            {
                if(imageFormat.ToString().Equals("jpeg", StringComparison.InvariantCultureIgnoreCase))
                {
                    using(EncoderParameters eps = new EncoderParameters(1))
                    {
                        eps.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, imageQulity);
                        img.Save(maskedImageSavePath, GetCodecInfo("image/jpeg"), eps);
                    }
                }
                else
                {
                    img.Save(maskedImageSavePath, imageFormat);
                }

                return maskedImageSavePath;
            }
        }
        #endregion

        #region DrawWaterMarkText
        public static Image DrawWaterMarkText(Image sourceImage, string text, WaterMarkPosition position, float lucencyValue, Color backgroundColor,
                                              Color fontColor, Font font)
        {
            Image m_image = new Bitmap(sourceImage);
            Brush brush = new SolidBrush(fontColor);
            SizeF size;

            using(Graphics g = Graphics.FromImage(m_image))
            {
                size = g.MeasureString(text, font);
            }

            Bitmap bitmap = new Bitmap((int)size.Width, (int)size.Height);
            bitmap.SetResolution(m_image.HorizontalResolution, m_image.VerticalResolution);

            using(Graphics g = Graphics.FromImage(bitmap))
            {
                g.DrawString(text, font, brush, 0, 0);
            }

            Image textWatermark = bitmap as Image;
            m_image = DrawWaterMarkImage(sourceImage, textWatermark, position, lucencyValue, backgroundColor);

            return m_image;
        }

        public static string DrawWaterMarkText(Image sourceImage, string text, WaterMarkPosition position, float lucencyValue, Color backgroundColor,
                                               Color fontColor, Font font, ImageFormat imageFormat, string maskedImageSavePath)
        {
            using(Image img = DrawWaterMarkText(sourceImage.Clone() as Image, text, position, lucencyValue, backgroundColor, fontColor, font))
            {
                if(imageFormat.ToString().Equals("jpeg", StringComparison.InvariantCultureIgnoreCase))
                {
                    using(EncoderParameters eps = new EncoderParameters(1))
                    {
                        eps.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, imageQulity);
                        img.Save(maskedImageSavePath, GetCodecInfo("image/jpeg"), eps);
                    }
                }
                else
                {
                    img.Save(maskedImageSavePath, imageFormat);
                }

                return maskedImageSavePath;
            }
        }
        #endregion

        #region DrawThumbnailImage
        public static Bitmap DrawThumbnailImage(Image sourceImage, int toWidth, int toHeight)
        {
            Bitmap bmp = new Bitmap(toWidth, toHeight, PixelFormat.Format32bppArgb);

            using(Graphics g = Graphics.FromImage(bmp))
            {
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;

                g.Clear(Color.Transparent);
                g.DrawImage(sourceImage, new Rectangle(0, 0, toWidth, toHeight),
                    new Rectangle(0, 0, sourceImage.Width, sourceImage.Height), GraphicsUnit.Pixel);
            }

            return bmp;
        }

        public static string DrawThumbnailImage(Image sourceImage, int toWidth, int toHeight, ImageFormat imageFormat, string thumnailImageSavePath)
        {
            using(Bitmap bmp = DrawThumbnailImage(sourceImage, toWidth, toHeight))
            {
                if(imageFormat.ToString().Equals("jpeg", StringComparison.InvariantCultureIgnoreCase))
                {
                    using(EncoderParameters eps = new EncoderParameters(1))
                    {
                        eps.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, imageQulity);
                        bmp.Save(thumnailImageSavePath, GetCodecInfo("image/jpeg"), eps);
                    }
                }
                else
                {
                    bmp.Save(thumnailImageSavePath, imageFormat);
                }

                return thumnailImageSavePath;
            }
        }
        #endregion

        #region private method
        private static ImageAttributes ImageAttrib(float lucencyValue)
        {
            float[][] matrixItems =
            {
                new float[] {1, 0, 0, 0, 0},
                new float[] {0, 1, 0, 0, 0},
                new float[] {0, 0, 1, 0, 0},
                new float[] {0, 0, 0, lucencyValue/100f, 0},
                new float[] {0, 0, 0, 0, 1}
            };

            ColorMatrix colorMatrix = new ColorMatrix(matrixItems);
            ImageAttributes imgAttr = new ImageAttributes();
            imgAttr.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
            return imgAttr;
        }

        private static ImageCodecInfo GetCodecInfo(string mimeType)
        {
            ImageCodecInfo[] CodecInfo = ImageCodecInfo.GetImageEncoders();

            foreach(ImageCodecInfo ici in CodecInfo)
            {
                if(ici.MimeType.Equals(mimeType, StringComparison.InvariantCultureIgnoreCase))
                    return ici;
            }
            return null;
        }
        #endregion
    }
}
